package cn.com.nes.site.service.equipment.archives;

import cn.com.nes.common.annotation.CallCenterTransactional;
import cn.com.nes.common.exception.IllegalBusinessException;
import cn.com.nes.common.util.MathUtils;
import cn.com.nes.common.util.XzqhUtils;
import cn.com.nes.mybatis.callcenter.entity.*;
import cn.com.nes.mybatis.callcenter.mapper.*;
import cn.com.nes.site.entity.bo.callcenter.*;
import cn.com.nes.site.entity.dto.call.PersonalProjectPageDto;
import cn.com.nes.site.entity.em.BusinessType;
import cn.com.nes.site.entity.em.DeleteEnum;
import cn.com.nes.site.entity.em.MaintainWorkOrderStautsEnum;
import cn.com.nes.site.entity.em.WorkOrderStautsEnum;
import cn.com.nes.site.entity.vo.project.PersonalProjectPageVo;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 长效管护设备档案处理类
 */
@Slf4j
@Service
public class CallCenterEquipmentArchivesHandle {

    @Resource
    private EquipmentInfoMapper equipmentInfoMapper;

    @Resource
    private HouseInfoMapper houseInfoMapper;

    @Resource
    private MasterInfoMapper masterInfoMapper;

    @Resource
    private ClientInfoMapper clientInfoMapper;

    @Resource
    private HouseMasterMapper houseMasterMapper;

    @Resource
    private EquipmentCompanyMapper equipmentCompanyMapper;

    @Resource
    private EquipmentTypeMapper equipmentTypeMapper;

    @Resource
    private HouseClienteleMapper houseClienteleMapper;

    @Resource
    private CompanyEquipmentPermissionMapper companyEquipmentPermissionMapper;

    @Resource
    private TXzqhMapper tXzqhMapper;

    @Resource
    private CallWorkOrderInfoMapper callWorkOrderInfoMapper;

    @Resource
    private WorkOrderRecordMapper workOrderRecordMapper;

    /**
     * 保存设备档案数据
     * @param bo 长效管护设备档案模型
     */
    @CallCenterTransactional
    public void saveEquipmentArchives(CallCenterEquipmentArchivesBo bo) throws Exception {
        // 保存房屋信息
        HouseInfo houseInfo = saveHouse(bo);

        // 保存设备信息
        List<EquipmentInfo> saveEquipments = saveEquipment(bo, houseInfo);

        if (CollUtil.isNotEmpty(saveEquipments)) {
            for (EquipmentInfo saveEquipment : saveEquipments) {

                // 保存客户信息
                ClientInfo clientInfo = saveClient(bo, saveEquipment);

                // 保存客户房屋关系
                saveHouseClientele(bo, houseInfo, clientInfo);

                // 保存户主信息
                MasterInfo masterInfo = saveMaster(bo, clientInfo);

                // 保存房屋户主关系
                saveHouseMaster(bo, houseInfo, masterInfo);

                // 保存设备授权信息
                CompanyEquipmentPermission permission = saveEquipmentPermission(houseInfo, clientInfo, saveEquipment);

                // 保存安装工单信息
                WorkOrderInfo workOrderInfo = saveWorkOrderInfo(houseInfo, clientInfo, saveEquipment, bo);


            }
        }
    }

    private WorkOrderRecord saveWorkOrderRecord(WorkOrderInfo workOrderInfo) throws Exception {
        WorkOrderRecord workOrderRecord = new WorkOrderRecord();
        workOrderRecord.setWorkOrderId(workOrderInfo.getId());
        workOrderRecord.setDesc("创建安装工单");
        workOrderRecord.setUserId(workOrderInfo.getUserId());
        workOrderRecord.setMaintainId(workOrderInfo.getMaintainId());
        workOrderRecord.setStatus(workOrderRecord.getStatus());
        workOrderRecord.setIsDelete(DeleteEnum._0.getKey());
        workOrderRecord.setGmtCreate(workOrderInfo.getGmtCreate());
        workOrderRecord.setGmtModified(workOrderInfo.getGmtModified());
        workOrderRecordMapper.insert(workOrderRecord);
        return workOrderRecord;
    }


    /**
     * 保存安装工单
     * @param houseInfo     房屋信息
     * @param clientInfo    客户信息
     * @param equipmentInfo 设备信息
     * @param bo            档案保存模型
     * @return
     */
    private WorkOrderInfo saveWorkOrderInfo(HouseInfo houseInfo, ClientInfo clientInfo, EquipmentInfo equipmentInfo,
            CallCenterEquipmentArchivesBo bo) throws Exception {
        WorkOrderInfo query = new WorkOrderInfo();
        query.setHouseId(houseInfo.getId());
        query.setEquipmentIds(equipmentInfo.getSbId());
        query.setClienteleId(clientInfo.getId());
        query.setWorkTypeId(33L);
        WorkOrderInfo exist = callWorkOrderInfoMapper.selectOne(new LambdaQueryWrapper<>(query));
        if (ObjectUtil.isNotNull(exist)) {
            return exist;
        }

        // 保存工单信息
        WorkOrderInfo workOrderInfo = convertToWorkOrder(houseInfo, clientInfo, bo);
        callWorkOrderInfoMapper.insert(workOrderInfo);

        // 保存安装工单记录
        saveWorkOrderRecord(workOrderInfo);
        return workOrderInfo;
    }

    @NotNull
    private WorkOrderInfo convertToWorkOrder(HouseInfo houseInfo, ClientInfo clientInfo,
            CallCenterEquipmentArchivesBo bo) {
        WorkOrderInfo workOrderInfo = new WorkOrderInfo();
        workOrderInfo.setCompanyId(bo.getCallCenterCompanyId());
        workOrderInfo.setClienteleId(clientInfo.getId());
        workOrderInfo.setContact(clientInfo.getName());
        workOrderInfo.setContactPhone(clientInfo.getPhone());
        workOrderInfo.setHouseId(houseInfo.getId());
        workOrderInfo.setAddress(houseInfo.getAddress());
        workOrderInfo.setWorkTypeId(33L);
        workOrderInfo.setMaintainStatus(Integer.parseInt(MaintainWorkOrderStautsEnum._3.getKey()));
        workOrderInfo.setStatus(Integer.parseInt(WorkOrderStautsEnum._2.getKey()));
        workOrderInfo.setMaintainId(bo.getMaintainanceUserId());
        workOrderInfo.setVerificationCode(MathUtils.randomDigitNumber(4));
        workOrderInfo.setIsDelete(DeleteEnum._0.getKey());
        workOrderInfo.setUserId(bo.getOperateUserId());
        workOrderInfo.setGmtCreate(bo.getOperateTimeStamp());
        workOrderInfo.setGmtModified(bo.getOperateTimeStamp());
        return workOrderInfo;
    }

    private CompanyEquipmentPermission saveEquipmentPermission(HouseInfo houseInfo, ClientInfo clientInfo,
            EquipmentInfo equipmentInfo) {
        CompanyEquipmentPermission companyEquipmentPermission = createCompanyEquipmentPermission(houseInfo, clientInfo, equipmentInfo);

        CompanyEquipmentPermission existEquipmentPermission = companyEquipmentPermissionMapper.findCompanyEquipmentPermissionUnDelete(equipmentInfo.getCompanyId(), equipmentInfo.getSbId(), equipmentInfo.getDdId());
        if (ObjectUtil.isNotNull(existEquipmentPermission)) {
            companyEquipmentPermission.setId(existEquipmentPermission.getId());
        }
        if (ObjectUtil.isNull(companyEquipmentPermission.getId())) {
            companyEquipmentPermissionMapper.insert(companyEquipmentPermission);
        } else {
            companyEquipmentPermissionMapper.updateById(companyEquipmentPermission);
        }
        return companyEquipmentPermission;
    }

    private CompanyEquipmentPermission createCompanyEquipmentPermission(HouseInfo houseInfo, ClientInfo clientInfo,
            EquipmentInfo equipmentInfo) {
        CompanyEquipmentPermission companyEquipmentPermission = new CompanyEquipmentPermission();
        companyEquipmentPermission.setCompanyId(equipmentInfo.getCompanyId());
        companyEquipmentPermission.setSbId(equipmentInfo.getSbId());
        companyEquipmentPermission.setDdId(equipmentInfo.getDdId());
        companyEquipmentPermission.setEquipmentCompanyId(equipmentInfo.getEquipmentCompanyId());
        companyEquipmentPermission.setEquipmentCompanyName(equipmentInfo.getEquipmentCompanyInfo());
        companyEquipmentPermission.setMasterName(clientInfo.getName());
        companyEquipmentPermission.setMasterPhone(clientInfo.getPhone());
        companyEquipmentPermission.setSblxId(equipmentInfo.getSbLxid());
        companyEquipmentPermission.setEquipmentCategory("");
        companyEquipmentPermission.setEquipmentModel("");
        companyEquipmentPermission.setHouseXzqhdm(houseInfo.getXzqhdm());
        companyEquipmentPermission.setHouseAddress(houseInfo.getAddress());
        companyEquipmentPermission.setHouseMph(houseInfo.getMph());
        companyEquipmentPermission.setEnergyType(1);
        companyEquipmentPermission.setWarrantyExpiryDate(equipmentInfo.getWarrantyExpiryDate());
        companyEquipmentPermission.setInstallationDate(new Date(equipmentInfo.getAzrq()));
        companyEquipmentPermission.setGmtCreate(new Date(equipmentInfo.getGmtCreate()));

        return companyEquipmentPermission;
    }

    @NotNull
    private List<EquipmentInfo> saveEquipment(CallCenterEquipmentArchivesBo bo, HouseInfo houseInfo) throws Exception {
        List<EquipmentInfo> saveEquipmentList = new ArrayList<>();
        //  通过前端传过来的厂商公司ID，查询长效管护的设备公司ID
        EquipmentCompany equipmentCompany = getEquipmentCompany(bo.getManufactureId());
        if (ObjectUtil.isNull(equipmentCompany)) {
            throw new IllegalBusinessException("设备公司不存在");
        }

        List<EquipmentSaveBo> equipmentSaveBos = bo.toEquipmentSaveBoList(houseInfo.getId(), equipmentCompany);
        for (EquipmentSaveBo equipmentSaveBo : equipmentSaveBos) {
            // 根据设备ID查询主键ID
            EquipmentInfo existEquipment = equipmentInfoMapper.findEquipmentInfoUnDelete(equipmentSaveBo.getSbId());
            if (ObjectUtil.isNotNull(existEquipment)) {
                equipmentSaveBo.setId(existEquipment.getId());
            }
            //  运营平台的设备类型和长效管护的设备类型一致，所以先根据前端传入的设备类型ID，查询长效管护的设备类型信息
            EquipmentType equipmentType = equipmentTypeMapper.getEquipmentUnDelete(equipmentSaveBo.getSbLxid());
            if (ObjectUtil.isNull(equipmentType)) {
                throw new IllegalBusinessException("设备类型不存在");
            }
            equipmentSaveBo.setEquipmentTypeId(equipmentType.getId());

            //  添加设备信息
            EquipmentInfo equipmentInfo = saveEquipmentInfo(equipmentSaveBo);
            saveEquipmentList.add(equipmentInfo);
        }
        return saveEquipmentList;
    }

    @NotNull
    private HouseMaster saveHouseMaster(CallCenterEquipmentArchivesBo bo, HouseInfo houseInfo,
            MasterInfo masterInfo) throws Exception {
        HouseMasterSaveBo houseMasterSaveBo = bo.convertToHouseMasterSaveDto(houseInfo.getId(), masterInfo.getId());
        HouseMaster existHouseMaster = houseMasterMapper.findHouseMaster(houseInfo.getId());
        if (ObjectUtil.isNotNull(existHouseMaster)) {
            return existHouseMaster;
        }

        //  添加房屋户主关系
        HouseMaster houseMaster = saveHouseMaster(houseMasterSaveBo);
        return houseMaster;
    }

    @NotNull
    private MasterInfo saveMaster(CallCenterEquipmentArchivesBo bo, ClientInfo clientInfo) throws Exception {
        MasterSaveBo masterSaveBo = bo.convertToMasterSaveDto(clientInfo.getId());
        MasterInfo existMaster = masterInfoMapper.findMasterInfo(clientInfo.getId());
        if (ObjectUtil.isNotNull(existMaster)) {
            masterSaveBo.setId(existMaster.getId());
        }
        //  添加户主信息
        MasterInfo masterInfo = saveMasterInfo(masterSaveBo);
        return masterInfo;
    }

    @NotNull
    private HouseClientele saveHouseClientele(CallCenterEquipmentArchivesBo bo, HouseInfo houseInfo,
            ClientInfo clientInfo) throws Exception {
        HouseClienteleSaveBo houseClienteleSaveBo = bo.covertToHouseClienteleSaveDto(houseInfo.getId(), clientInfo.getId());
        HouseClientele existHouseClientele = houseClienteleMapper.findHouseClient(houseInfo.getId(), clientInfo.getId());
        if (ObjectUtil.isNotNull(existHouseClientele)) {
            return existHouseClientele;
        }
        // 房屋和客户关系信息
        HouseClientele houseClientele = saveHouseClientele(houseClienteleSaveBo);
        return houseClientele;
    }

    @NotNull
    private ClientInfo saveClient(CallCenterEquipmentArchivesBo bo, EquipmentInfo equipmentInfo) throws Exception {
        ClientSaveBo clientSaveBo = bo.convertToClientSaveDto();
        ClientInfo existClient = clientInfoMapper.findClient(bo.getDdId(), equipmentInfo.getSbId(), bo.getIdCardNumber());
        if (ObjectUtil.isNotNull(existClient)) {
            clientSaveBo.setId(existClient.getId());
        }
        //  添加客户信息
        ClientInfo clientInfo = saveClientInfo(clientSaveBo);
        return clientInfo;
    }

    @NotNull
    private HouseInfo saveHouse(CallCenterEquipmentArchivesBo bo) throws Exception {
        HouseSaveBo houseSaveBo = bo.toHouseSaveDto();
        //  查询房屋信息
        HouseInfo existHouse = houseInfoMapper.selectById(bo.getDdId());
        if (ObjectUtil.isNotNull(existHouse)) {
            houseSaveBo.setId(existHouse.getId());
        }
        //  添加房屋信息
        HouseInfo houseInfo = saveHouseInfo(houseSaveBo);
        return houseInfo;
    }

    /**
     * 保存房屋客户关系
     * @param bo
     * @return
     */
    private HouseClientele saveHouseClientele(HouseClienteleSaveBo bo) throws Exception {
        HouseClientele houseClientele = bo.toHouseClientele();
        if (ObjectUtil.isNull(houseClientele.getId())) {
            houseClientele.setGmtCreate(bo.getGmtCreate());
            houseClienteleMapper.insert(houseClientele);
        } else {
            houseClientele.setGmtModified(bo.getGmtModified());
            houseClienteleMapper.updateById(houseClientele);
        }
        return houseClientele;
    }


    /**
     * 保存房屋户主关系
     * @param bo
     * @return
     */
    private HouseMaster saveHouseMaster(HouseMasterSaveBo bo) throws Exception {
        HouseMaster houseMaster = bo.toHouseMaster();
        if (ObjectUtil.isNull(houseMaster.getId())) {
            houseMaster.setGmtCreate(bo.getGmtCreate());
            houseMasterMapper.insert(houseMaster);
        } else {
            houseMaster.setGmtModified(bo.getGmtModified());
            houseMasterMapper.updateById(houseMaster);
        }
        return houseMaster;
    }

    /**
     * 保存客户信息
     * @param bo
     * @return
     */
    private ClientInfo saveClientInfo(ClientSaveBo bo) throws Exception {
        ClientInfo clientInfo = bo.toClientInfoDo();
        if (ObjectUtil.isNull(clientInfo.getId())) {
            clientInfo.setDeleted(DeleteEnum._0.getKey());
            clientInfo.setGmtCreate(bo.getGmtCreate());
            clientInfoMapper.insert(clientInfo);
        } else {
            clientInfo.setGmtModified(bo.getGmtModified());
            clientInfoMapper.updateById(clientInfo);
        }
        return clientInfo;
    }

    /**
     * 保存户主信息
     * @param bo
     * @return
     */
    private MasterInfo saveMasterInfo(MasterSaveBo bo) throws Exception {
        MasterInfo masterInfo = bo.toMasterInfoDo();
        if (ObjectUtil.isNull(masterInfo.getId())) {
            masterInfo.setDeleted(DeleteEnum._0.getKey());
            masterInfo.setGmtCreate(bo.getGmtCreate());
            masterInfoMapper.insert(masterInfo);
        } else {
            masterInfo.setGmtModified(bo.getGmtModified());
            masterInfoMapper.updateById(masterInfo);
        }
        return masterInfo;
    }

    /**
     * 保存房屋信息
     * @param bo
     * @return
     */
    private HouseInfo saveHouseInfo(HouseSaveBo bo) throws Exception {
        HouseInfo houseInfo = bo.toHouseInfoDo();
        if (ObjectUtil.isNull(houseInfo.getId())) {
            houseInfo.setDeleted(DeleteEnum._0.getKey());
            houseInfo.setGmtCreate(System.currentTimeMillis());
            houseInfoMapper.insert(houseInfo);
        } else {
            houseInfo.setGmtModified(System.currentTimeMillis());
            houseInfoMapper.updateById(houseInfo);
        }
        return houseInfo;
    }

    /**
     * 查询设备公司
     * @param manufactureId
     * @return
     */
    private EquipmentCompany getEquipmentCompany(String manufactureId) throws Exception {
        return equipmentCompanyMapper.getCompanyUnDelete(manufactureId);
    }

    /**
     * 保存设备信息
     * @param bo 设备数据保存模型
     * @return
     */
    private EquipmentInfo saveEquipmentInfo(EquipmentSaveBo bo) throws Exception {
        EquipmentInfo equipmentInfo = bo.toEquipmnetInfoDo();
        if (ObjectUtil.isNull(equipmentInfo.getId())) {
            equipmentInfoMapper.insert(equipmentInfo);
        } else {
            equipmentInfoMapper.updateById(equipmentInfo);
        }
        return equipmentInfo;
    }

    /**
     * 个人项目列表-分页
     * @param vo 个人项目分页查询模型
     * @return
     */
    public List<PersonalProjectPageDto> pagePersonalProject(Page<PersonalProjectPageDto> page,
            PersonalProjectPageVo vo) throws Exception {
        // 处理行政区划不同级别的行政区划
        if (StrUtil.isNotEmpty(vo.getAreaCode())) {
            String AreaCodeLevel = tXzqhMapper.getAreaCodeLevel(vo.getAreaCode());
            String areaCodeLikeStr = XzqhUtils.getAreaCodeLikeStr(vo.getAreaCode(), AreaCodeLevel);
            vo.setAreaCode(areaCodeLikeStr);
        }

        List<PersonalProjectPageDto> personalProjectPageDtos = equipmentInfoMapper.pagePersonalProject(page, vo);
        for (PersonalProjectPageDto personalProjectPageDto : personalProjectPageDtos) {
            personalProjectPageDto.setInstallType(BusinessType.getVal(personalProjectPageDto.getInstallType()));
            personalProjectPageDto.setOrderStatusName(StrUtil.blankToDefault(WorkOrderStautsEnum.getVal(personalProjectPageDto.getOrderStatus()), ""));
        }
        return personalProjectPageDtos;
    }


}
